package com.changgou.order.service.impl;

import com.changgou.goods.feign.SkuFeign;
import com.changgou.order.dao.OrderItemMapper;
import com.changgou.order.dao.OrderLogMapper;
import com.changgou.order.dao.OrderMapper;
import com.changgou.order.dao.RemindMapper;
import com.changgou.order.pojo.Order;
import com.changgou.order.pojo.OrderItem;
import com.changgou.order.pojo.OrderLog;
import com.changgou.order.pojo.Remind;
import com.changgou.order.service.CartService;
import com.changgou.order.service.OrderService;
import com.changgou.user.feign.UserFeign;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import entity.DateUtil;
import entity.IdWorker;
import entity.RedisConfig;
import entity.TokenDecode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;

/****
 * @Author:keda
 * @Description:Order业务层接口实现类
 * @Date 2019/6/14 0:16
 *****/
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private CartService cartService;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SkuFeign skuFeign;
    @Autowired
    private UserFeign userFeign;
    @Autowired
    private OrderLogMapper orderLogMapper;
    @Autowired
    private TokenDecode tokenDecode;
    @Autowired
    private RemindMapper remindMapper;


    /**
     * 根据用户名分页排序条件查询订单
     * @param order
     * @param page
     * @return
     */
    @Override
    public Map<String, Object> findAllOrder(Order order, int page) {
        String username=tokenDecode.getUserInfo().get("username");

        if (order==null){
            order = new Order();
        }
        order.setUsername(username);
        //查询条件封装
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        // 订单未删除
        criteria.andIsNull("isDelete");
        // 用户名称
        if (!StringUtils.isEmpty(username)) {
            criteria.andEqualTo("username", username);
        }
        //订单Id
        if (order.getId()!=null){
            criteria.andEqualTo("id", order.getId());
        }
        //shippingCode，0：查询全部，1：查询待付款，2：查询待收货，3：查询待评价
        if(!StringUtils.isEmpty(order.getShippingCode()) && !order.getShippingCode().equals("0")) {
            // 【已下单，待付款】支付状态，0：未支付，1：已支付，2：支付失败
            if (!StringUtils.isEmpty(order.getShippingCode()) && order.getShippingCode().equals("1")) {
                criteria.andEqualTo("orderStatus", "0");//订单未完成
                criteria.andNotEqualTo("payStatus", "1");//未支付或者支付失败
                criteria.andEqualTo("consignStatus","0");//订单未发货
            }
            // 【已付款，待收货】发货状态，0：未发货，1：已发货，2：已收货
            if (!StringUtils.isEmpty(order.getShippingCode()) && order.getShippingCode().equals("2")) {
                criteria.andEqualTo("orderStatus", "0");//订单未完成
                criteria.andEqualTo("payStatus", "1");//已支付
                criteria.andNotEqualTo("consignStatus", "2");//未收货或者未到货
            }
            // 【已收货，待评价】是否评价，0：待评价，1：已评价
            if (!StringUtils.isEmpty(order.getShippingCode()) && order.getShippingCode().equals("3")) {
                criteria.andEqualTo("orderStatus", "1");//订单未完成
                criteria.andEqualTo("payStatus", "1");//已支付
                criteria.andEqualTo("consignStatus", "2");//已收货
                criteria.andEqualTo("buyerRate", "0");//未评价
            }
        }
        //分页排序设置
        PageHelper.startPage(page, 3).setOrderBy("create_time DESC");
        //通过用户名和未删除状态查询所有订单
        List<Order> orderList = orderMapper.selectByExample(example);
        PageInfo<Order> pageInfo = new PageInfo<>(orderList);
        //封装返回结果
        Map<String, Object> dataMap = new HashMap<>();
        ArrayList<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>();
        for (Order orderResult : pageInfo.getList()) {
            Map<String, Object> orderMap = new HashMap<String, Object>();
                //每个订单
                orderMap.put("order",orderResult);
                //存储需要转换格式的时间
                orderMap.put("createTime",DateUtil.data2str(orderResult.getCreateTime(),DateUtil.PATTERN_YYYY_MM_DDHHMM));
                //订单详情
                OrderItem orderItem = new OrderItem();
                orderItem.setOrderId(orderResult.getId());
                List<OrderItem> orderItemList = orderItemMapper.select(orderItem);
                orderMap.put("orderItemList",orderItemList);
                dataList.add(orderMap);
        }
        dataMap.put("list",dataList);
        dataMap.put("pageNum",pageInfo.getPageNum());
        dataMap.put("pageSize",pageInfo.getPageSize());
        dataMap.put("size",pageInfo.getSize());
        dataMap.put("startRow",pageInfo.getStartRow());
        dataMap.put("endRow",pageInfo.getEndRow());
        dataMap.put("total",pageInfo.getTotal());
        dataMap.put("pages",pageInfo.getPages());
        dataMap.put("hasPreviousPage",pageInfo.isHasPreviousPage());
        dataMap.put("hasNextPage",pageInfo.isHasNextPage());
        return dataMap;
    }

    /**
     * 查询所有状态订单个数
     * @return
     */
    @Override
    public Map<String, Object> findCount() {
        String username=tokenDecode.getUserInfo().get("username");

        //全部订单个数
        int allCount = selectCountByStatus(username,null);
        //未支付个数
        int payStatusCount = selectCountByStatus(username,"payStatusCount");
        //待收货个数
        int consignStatusCount = selectCountByStatus(username,"consignStatusCount");
        //待评价个数
        int buyerRateCount = selectCountByStatus(username,"buyerRateCount");
        //返回结果封装
        HashMap<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("allCount",allCount);
        dataMap.put("payStatusCount",payStatusCount);
        dataMap.put("consignStatusCount",consignStatusCount);
        dataMap.put("buyerRateCount",buyerRateCount);
        return dataMap;
    }

    /**
     * 根据分类封装查询条件并查询个数
     * @param username
     * @param category 分类
     * @return
     */
    private int selectCountByStatus(String username,String category) {
        //查询条件封装
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        // 订单未删除
        criteria.andIsNull("isDelete");
        // 用户名称
        if (!StringUtils.isEmpty(username)) {
            criteria.andEqualTo("username", username);
        }
        if (category!=null) {
            //未支付
            if (category.equalsIgnoreCase("payStatusCount")) {
                criteria.andEqualTo("orderStatus", "0");//订单未完成
                criteria.andNotEqualTo("payStatus", "1");//未支付或者支付失败
            }
            //待收货
            if (category.equalsIgnoreCase("consignStatusCount")) {
                criteria.andEqualTo("orderStatus", "0");//订单未完成
                criteria.andEqualTo("payStatus", "1");//已支付
                criteria.andNotEqualTo("consignStatus", "2");//未收货或者未到货
            }
            //待评价
            if (category.equalsIgnoreCase("buyerRateCount")) {
                criteria.andEqualTo("orderStatus", "1");//订单已完成
                criteria.andEqualTo("payStatus", "1");//已支付
                criteria.andEqualTo("consignStatus", "2");//已收货
                criteria.andEqualTo("buyerRate", "0");//未评价
            }
        }
        return orderMapper.selectCountByExample(example);
    }

    /**
     * 根据id取消(修改状态)订单
     *
     * @param id
     */
    @Override
    public void CancellationOfOrder(String id) {
        Order order = orderMapper.selectByPrimaryKey(id);
        if (order.getOrderStatus().equalsIgnoreCase("0") &&  !order.getPayStatus().equalsIgnoreCase("1")&& order.getConsignStatus().equalsIgnoreCase("0")){
            //订单状态 3:已取消
            order.setOrderStatus("3");
            //关闭交易时间
            order.setCloseTime(new Date());
            orderMapper.updateByPrimaryKeySelective(order);
        }else {
            throw new RuntimeException("该订单不能取消");
        }
    }

    /**
     * 确认收货(修改状态)
     *
     * @param id
     */
    @Override
    public void confirmReceipt(String id) {
        Order order = orderMapper.selectByPrimaryKey(id);
        if (!order.getConsignStatus().equalsIgnoreCase("2")&& order.getPayStatus().equalsIgnoreCase("1") && order.getOrderStatus().equalsIgnoreCase("0")) {
            //订单状态 1:已完成
            order.setOrderStatus("1");
            //交易完成时间
            order.setEndTime(new Date());
            //发货状态
            order.setConsignStatus("2");
            orderMapper.updateByPrimaryKeySelective(order);
        }
    }

    /**
     * 提醒发货(查询数据库)
     *
     * @param orderId : 订单id
     * @return
     */
    @Override
    public Remind remindTheShipment(String orderId) {
        Example example = new Example(Remind.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo(orderId);
        return remindMapper.selectOneByExample(example);
    }

    /**
     * 增加发货数据
     *
     * @param orderId
     */
    @Override
    public void addRemind(String orderId) {
        Remind remind = new Remind();
        remind.setOrderId(orderId);
        remind.setDate(new Date());
        remind.setId(String.valueOf(idWorker.nextId()));
        remind.setStatus("1");
        remindMapper.insert(remind);
    }


    /**
     * 修改状态
     */
    @Override
    public void updateRemindStatus(String id) {
        Remind remind = remindMapper.selectByPrimaryKey(id);
        remind.setStatus("1");
        remindMapper.updateByPrimaryKey(remind);
    }

    /**
     * 删除订单(修改状态)
     * @param orderId
     */
    @Override
    public void deleteOrder(String orderId) {
        Order order = orderMapper.selectByPrimaryKey(orderId);
        if (order.getOrderStatus().equalsIgnoreCase("1") || order.getOrderStatus().equalsIgnoreCase("2") || order.getOrderStatus().equalsIgnoreCase("3")) {
            order.setIsDelete("1");
            orderMapper.updateByPrimaryKeySelective(order);
        }
    }

    /**
     * Order条件+分页查询
     *
     * @param order 查询条件
     * @param page  页码
     * @param size  页大小
     * @return 分页结果
     */
    @Override
    public PageInfo<Order> findPage(Order order, int page, int size) {
        //分页
        PageHelper.startPage(page, size);
        //搜索条件构建
        Example example = createExample(order);
        //执行搜索
        return new PageInfo<Order>(orderMapper.selectByExample(example));
    }

    /**
     * Order分页查询
     *
     * @param page
     * @param size
     * @return
     */
    @Override
    public PageInfo<Order> findPage(int page, int size) {
        //静态分页
        PageHelper.startPage(page, size);
        //分页查询
        return new PageInfo<Order>(orderMapper.selectAll());
    }

    /**
     * Order条件查询
     *
     * @param order
     * @return
     */
    @Override
    public List<Order> findList(Order order) {
        //构建查询条件
        Example example = createExample(order);
        //根据构建的条件查询数据
        return orderMapper.selectByExample(example);
    }


    /**
     * Order构建查询对象
     *
     * @param order
     * @return
     */
    public Example createExample(Order order) {
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        if (order != null) {
            // 订单id
            if (!StringUtils.isEmpty(order.getId())) {
                criteria.andEqualTo("id", order.getId());
            }
            // 数量合计
            if (!StringUtils.isEmpty(order.getTotalNum())) {
                criteria.andEqualTo("totalNum", order.getTotalNum());
            }
            // 金额合计
            if (!StringUtils.isEmpty(order.getTotalMoney())) {
                criteria.andEqualTo("totalMoney", order.getTotalMoney());
            }
            // 优惠金额
            if (!StringUtils.isEmpty(order.getPreMoney())) {
                criteria.andEqualTo("preMoney", order.getPreMoney());
            }
            // 邮费
            if (!StringUtils.isEmpty(order.getPostFee())) {
                criteria.andEqualTo("postFee", order.getPostFee());
            }
            // 实付金额
            if (!StringUtils.isEmpty(order.getPayMoney())) {
                criteria.andEqualTo("payMoney", order.getPayMoney());
            }
            // 支付类型，1、在线支付、0 货到付款
            if (!StringUtils.isEmpty(order.getPayType())) {
                criteria.andEqualTo("payType", order.getPayType());
            }
            // 订单创建时间
            if (!StringUtils.isEmpty(order.getCreateTime())) {
                criteria.andEqualTo("createTime", order.getCreateTime());
            }
            // 订单更新时间
            if (!StringUtils.isEmpty(order.getUpdateTime())) {
                criteria.andEqualTo("updateTime", order.getUpdateTime());
            }
            // 付款时间
            if (!StringUtils.isEmpty(order.getPayTime())) {
                criteria.andEqualTo("payTime", order.getPayTime());
            }
            // 发货时间
            if (!StringUtils.isEmpty(order.getConsignTime())) {
                criteria.andEqualTo("consignTime", order.getConsignTime());
            }
            // 交易完成时间
            if (!StringUtils.isEmpty(order.getEndTime())) {
                criteria.andEqualTo("endTime", order.getEndTime());
            }
            // 交易关闭时间
            if (!StringUtils.isEmpty(order.getCloseTime())) {
                criteria.andEqualTo("closeTime", order.getCloseTime());
            }
            // 物流名称
            if (!StringUtils.isEmpty(order.getShippingName())) {
                criteria.andEqualTo("shippingName", order.getShippingName());
            }
            // 物流单号
            if (!StringUtils.isEmpty(order.getShippingCode())) {
                criteria.andEqualTo("shippingCode", order.getShippingCode());
            }
            // 用户名称
            if (!StringUtils.isEmpty(order.getUsername())) {
                criteria.andLike("username", "%" + order.getUsername() + "%");
            }
            // 买家留言
            if (!StringUtils.isEmpty(order.getBuyerMessage())) {
                criteria.andEqualTo("buyerMessage", order.getBuyerMessage());
            }
            // 是否评价
            if (!StringUtils.isEmpty(order.getBuyerRate())) {
                criteria.andEqualTo("buyerRate", order.getBuyerRate());
            }
            // 收货人
            if (!StringUtils.isEmpty(order.getReceiverContact())) {
                criteria.andEqualTo("receiverContact", order.getReceiverContact());
            }
            // 收货人手机
            if (!StringUtils.isEmpty(order.getReceiverMobile())) {
                criteria.andEqualTo("receiverMobile", order.getReceiverMobile());
            }
            // 收货人地址
            if (!StringUtils.isEmpty(order.getReceiverAddress())) {
                criteria.andEqualTo("receiverAddress", order.getReceiverAddress());
            }
            // 订单来源：1:web，2：app，3：微信公众号，4：微信小程序  5 H5手机页面
            if (!StringUtils.isEmpty(order.getSourceType())) {
                criteria.andEqualTo("sourceType", order.getSourceType());
            }
            // 交易流水号
            if (!StringUtils.isEmpty(order.getTransactionId())) {
                criteria.andEqualTo("transactionId", order.getTransactionId());
            }
            // 订单状态,0:未完成,1:已完成，2：已退货
            if (!StringUtils.isEmpty(order.getOrderStatus())) {
                criteria.andEqualTo("orderStatus", order.getOrderStatus());
            }
            // 支付状态,0:未支付，1：已支付，2：支付失败
            if (!StringUtils.isEmpty(order.getPayStatus())) {
                criteria.andEqualTo("payStatus", order.getPayStatus());
            }
            // 发货状态,0:未发货，1：已发货，2：已收货
            if (!StringUtils.isEmpty(order.getConsignStatus())) {
                criteria.andEqualTo("consignStatus", order.getConsignStatus());
            }
            // 是否删除
            if (!StringUtils.isEmpty(order.getIsDelete())) {
                criteria.andEqualTo("isDelete", order.getIsDelete());
            }
        }
        return example;
    }

    /**
     * 删除
     *
     * @param id
     */
    @Override
    public void delete(String id) {
        orderMapper.deleteByPrimaryKey(id);
    }

    /**
     * 修改Order
     *
     * @param order
     */
    @Override
    public void update(Order order) {
        orderMapper.updateByPrimaryKey(order);
    }

    /**
     * 增加Order
     *
     * @param order
     * @return
     */
    @Override
    public int add(Order order) {
        RedisConfig.convertRedisTemplate(redisTemplate);
        //根据用户名查出购物车中所有商品
        List<OrderItem> orderItems = cartService.list(order.getUsername());

        //计算总价格
        int totalMoney = 0;
        int totalPayMoney = 0;
        int num = 0;
        for (OrderItem orderItem : orderItems) {
            //总价格
            totalMoney += orderItem.getMoney();
            //总实付价格
            totalPayMoney += orderItem.getPayMoney();
            //总数量
            num += orderItem.getNum();
        }

        order.setId("NO." + idWorker.nextId());
        order.setTotalNum(num);
        order.setTotalMoney(totalMoney);
        order.setPreMoney(totalMoney - totalPayMoney);
        order.setPayMoney(totalPayMoney);
        order.setCreateTime(new Date());
        order.setUpdateTime(order.getCreateTime());
        order.setBuyerRate("0");        //0:未评价，1：已评价
        order.setSourceType("1");       //来源，1：WEB
        order.setOrderStatus("0");      //0:未完成,1:已完成，2：已退货
        order.setPayStatus("0");        //0:未支付，1：已支付，2：支付失败
        order.setConsignStatus("0");    //0:未发货，1：已发货，2：已收货
        int count = orderMapper.insertSelective(order);

        //添加订单明细
        for (OrderItem orderItem : orderItems) {
            orderItem.setId("NO." + idWorker.nextId());
            orderItem.setOrderId(order.getId());
            orderItem.setIsReturn("0");
            orderItemMapper.insertSelective(orderItem);
        }

        //如果是线上支付，添加订单日志
        if (order.getPayType().equalsIgnoreCase("1")) {
            OrderLog orderLog = new OrderLog();
            orderLog.setId(String.valueOf(idWorker.nextId()));
            orderLog.setOrderId(order.getId());
            orderLog.setOrderStatus(order.getOrderStatus());
            orderLog.setPayStatus(order.getPayStatus());
            orderLog.setConsignStatus(order.getConsignStatus());
            orderLog.setMoney(order.getPayMoney());
            orderLog.setUsername(order.getUsername());
            orderLog.setRemarks("创建支付记录！");

            //根据用户名和日志id添加到redis缓存
            redisTemplate.boundHashOps("OrderLog").put(orderLog.getId(), orderLog);
            //添加日志id的队列信息，方便后面查询,主要是用于定时清理
            redisTemplate.boundListOps("OrderLogList").leftPush(orderLog.getId());
            //存储订单id与日志id的映射方便查询
            redisTemplate.boundHashOps("OrderMappingLog" + order.getUsername()).put(order.getId(), orderLog.getId());
        }

        //调用库存递减
        skuFeign.decrCount(order.getUsername());

        //调用增加积分
        userFeign.addPoints(order.getUsername(), order.getTotalNum() * 1);

        //清空redis中的购物车数据
        redisTemplate.delete("Cart_" + order.getUsername());
        return count;
    }

    /**
     * 根据ID查询Order
     *
     * @param id
     * @return
     */
    @Override
    public Order findById(String id) {
        return orderMapper.selectByPrimaryKey(id);
    }

    /**
     * 查询Order全部数据
     *
     * @return
     */
    @Override
    public List<Order> findAll() {
        return orderMapper.selectAll();
    }

    /***
     * 修改订单状态
     * @param username：用户登录名
     * @param orderId：订单ID
     * @param transactionId：交易流水号
     * @param orderLog:日志数据
     */
    @Override
    public void updateStatus(String username, String orderId, String transactionId, OrderLog orderLog) {
        RedisConfig.convertRedisTemplate(redisTemplate);

        //修改订单
        Order order = orderMapper.selectByPrimaryKey(orderId);
        order.setUpdateTime(new Date());
        order.setPayTime(order.getUpdateTime()); //正常来说应该填写微信返回的支付时间
        order.setTransactionId(transactionId); //交易流水号
        order.setPayStatus("1"); //已支付
        orderMapper.updateByPrimaryKeySelective(order);

        //修改日志状态并持久化
        orderLog.setPayStatus(order.getPayStatus()); //支付状态
        orderLogMapper.insertSelective(orderLog);

        //删除redis的日志缓存
        redisTemplate.boundHashOps("OrderLog").delete(orderLog.getId());
        redisTemplate.boundHashOps("OrderMappingLog" + username).delete(orderId);
    }

    /****
     * 取消超时未支付的订单
     * @param orderLog
     */
    @Override
    public void deleteOrder(OrderLog orderLog) {
        RedisConfig.convertRedisTemplate(redisTemplate);

        //取消订单
        Order order = orderMapper.selectByPrimaryKey(orderLog.getOrderId());
        order.setOrderStatus("2");
        order.setUpdateTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);

        //查询订单详情
        OrderItem orderItem = new OrderItem();
        orderItem.setOrderId(order.getId());
        List<OrderItem> orderItems = orderItemMapper.select(orderItem);
        //根据订单详情回滚库存
        if (orderItems != null && orderItems.size() > 0) {
            skuFeign.rollBackCount(orderItems);
        }

        //删除日志缓存
        redisTemplate.boundHashOps("OrderLog").delete(orderLog.getId());
        redisTemplate.boundHashOps("OrderMappingLog" + order.getUsername()).delete(order.getId());
    }
}
